package semantic_matching.doc_search.doc_tree;

import common.dao.elastic.ElasticSearchDao;
import common.dao.orient.OrientGraphDao;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import query_understanding.query_language.doc_entity_tree.DocumentQueryTree;
import query_understanding.query_language.doc_entity_tree.EntityQueryTree;
import query_understanding.query_understand.tree_progress.DocumentQueryProgress;
import query_understanding.query_understand.tree_selector.QueryTreeSelector;
import semantic_matching.common.schema.MatchedDocumentTree;
import semantic_matching.common.schema.MatchedEntites;
import semantic_matching.common.schema.MatchedEntityTree;
import semantic_matching.entity_search.entity_tree.EntityQueryMatcher;

import java.util.List;

/**
 * Created by julianzliu on 4/25/2017.
 */

@Component
public class DocumentQueryMatcher {

    static final Logger logger = LoggerFactory.getLogger(DocumentQueryMatcher.class);

    private EntityQueryMatcher treeMatcher;
    private ElasticSearchDao searchDao;
    private OrientGraphDao orientGraphDao;

    public DocumentQueryMatcher(){
        this.searchDao = new ElasticSearchDao();
        this.orientGraphDao = new OrientGraphDao();
        this.treeMatcher = new EntityQueryMatcher( this.searchDao, this.orientGraphDao );

    }


    public MatchedDocumentTree solveDocumentQueryProgress(DocumentQueryProgress progress){
        return matchDocumentQueryTree( progress.documentQueryTree );
    }


    private MatchedDocumentTree matchDocumentQueryTree(DocumentQueryTree tree){

        logger.info("[matchDocumentQueryTree] begin to solve matchDocumentQueryTree...");

        List<EntityQueryTree> entityQueryTreeList = tree.entityQueryTreeList;

        MatchedDocumentTree matchedDocumentTree = new MatchedDocumentTree();
        /*
        TODO:
        多线程优化 -> 同时查询多个子树 -> 最终同步
        不过目前绝大对数文档树只包含一棵子树
         */
        for(EntityQueryTree entityQueryTree: entityQueryTreeList){

            logger.info("[matchDocumentQueryTree] begin to solve entityTree {}", entityQueryTree.hashCode() );

            MatchedEntityTree matchedEntityTree = this.treeMatcher.matchEntityQueryTree( entityQueryTree );

            matchedDocumentTree.addMatchedEntityTree( matchedEntityTree );

        }

        return matchedDocumentTree;
    }






    /*********************************************************************************
     *
     * @param args
     */
    public static void main(String[] args){
        String query = "wife of Obama.";
        if(args.length > 0){
            query = "";
            for(String arg : args) query += " " + arg;
        }
        QueryTreeSelector selector  = new QueryTreeSelector();
        DocumentQueryProgress progress = selector.genDocQueryTree( query );

        DocumentQueryMatcher matcher = new DocumentQueryMatcher();
        MatchedDocumentTree matchedDocumentTree = matcher.solveDocumentQueryProgress( progress );

        for(MatchedEntityTree entityTree: matchedDocumentTree.matchedEntityTreeList){
            MatchedEntites rootEntites = entityTree.rootEntities;
            for(String entity: rootEntites.entities){
                System.out.println( "[rootEntites] tree = " + entityTree.hashCode() + " , entity = " +  entity );
            }
        }

    }
}
